library(GEOquery)
library(jsonlite)
library(SummarizedExperiment)
library(tidyverse)

arrays <- read_csv('mission/Array.txt', col_names = 'id')

arrays |> dplyr::count(id, sort = T)

arrays <- arrays |> distinct(id)

array5 <- arrays$id[1:5] |>
  map(\(x)getGEO(x, destdir = '~/append-ssd/geo_array/', AnnotGPL = T),
      .progress = T)

array.se <- arrays$id |>
  map(\(x)getGEO(x, destdir = '~/append-ssd/geo_array/', AnnotGPL = T),
      .progress = T)

array.se <- array.se |> list_c()

foo |> iwalk(\(x, idx)print(idx))

write_se_rds <- function(x, idx){
  path_rds <- str_c('~/append-ssd/geo_array/',
                    str_extract(idx, 'GSE\\d+'),
                    '.rds') 
  write_rds(x, path_rds)
}

foo |> iwalk(write_se_rds)

array.se[[1]] |> write_rds('exprset1.rds')

array.se[[1]]

example.json <- fromJSON('~/样品信息模板.json')

form_sample_attr <- function(x){
  f1.chara <- x@phenoData@data |>
    as_tibble(.name_repair = 'unique') |>
    select(contains('characteris'))
  
  attr.name <- f1.chara |>
    map(\(x)str_remove(x, ':.+')) |>
    map_chr(head, 1) |>
    make.names(unique = TRUE)
  
  colnames(f1.chara) <- attr.name
  
  f1.chara |> mutate(across(everything(), \(x)str_remove(x, '.+: ')))
}

write_se_jstb <- function(se, idx, tech){
  sample.tb <-
    tibble(gsm_accession = se$geo_accession,
           title = se$title,
           source = se$organism_ch1,
           treatment = se$source_name_ch1,
           attributes = form_sample_attr(se))
  
  series.tb <-
    tibble(geo_accession = str_extract(idx, 'GSE\\d+'),
           title = se@experimentData@title,
           platform = se@annotation,
           technology = se@experimentData@other[["type"]],
           year = se@experimentData@other$submission_date |> mdy() |> year(),
           samples = list(sample.tb))
}

jstb5 <- array.se |>
  imap(\(x,idx)write_se_jstb(x, idx, tech = 'array'),
       .progress = T)

datasts <- jstb5 |>
  list_rbind()

array.uniq <- datasts |>
  mutate(order = seq_along(geo_accession)) |>
  filter(!duplicated(str_c(geo_accession, platform)) & str_detect(technology, 'array')) |>
  pull(order)

array.se <- array.se[array.uniq]

curating.dis <- datasts |>
  distinct(geo_accession, platform, .keep_all = T) |>
  filter(str_detect(technology, 'array'))

curating.dis |> 
  mutate(disease = str_extract(title, 'riasis|IBD|SLE|RA|sclerosis')) |>
  select(geo_accession, title, disease) |>
  write_csv('curating.array.csv')

curated <- read_tsv('curating.array.csv') |>
  distinct(geo_accession, .keep_all = T)

curating.dis |>
  toJSON() |>
  prettify() |>
  cat(file = 'geo.aid.array.json')

curated <- curated |>
  right_join(curating.dis)

curated.file <- curated |>
  mutate(disease = str_replace(disease, 'ria', 'psoria') |>
           str_replace('sclerosis', 'MS'),
         filename = str_c(disease, year, sep = '_'))

curated.file |> tail() |> DT::datatable()

disyear <- curated.file$filename |> replace_na('psoriasis_2022')

gsegpl <- array.se |> names() |>
  str_remove('_series.+')

rds.name <- map2_chr(gsegpl, disyear, str_c, sep = "_")

rds.path <- rds.name |>
  map(\(x)str_c('~/append-ssd/geo_array/' ,x, '.rds'))

walk2(array.se, rds.path,
      \(x,y)write_rds(x,y), .progress = T)

created_date <- today() |> as.character()

tb.json |> cat(file = 'tibble.json')

foo.acc <- names(foo)

f1 <- foo[[1]]

# tidy file tree --------
paths <- list.files('~/append-ssd/geo_array', pattern = 'rds|txt.gz',
                       full.names = T)
paths

grow_db_tree <- function(paths, root.dir, regex = 'SLE'){
  need.paths <- paths |> str_subset(regex)
  need.geo <- need.paths |> str_extract('GSE\\d+')
  leave.dirs <- need.paths |> str_subset('rds') |>
    basename() |> str_remove('.rds') |>
    str_remove('-GPL\\d+') |> base::unique()
  
  message(str_glue('Found {length(leave.dirs)} unique GSE ID(s)'))
  
  stem.dir <- file.path(root.dir, regex)
  
  message(str_glue('Use {stem.dir} as stem dir'))
  dir.create(stem.dir)
  
  grow_leave <- function(leave.dir) {
    leave.path <- file.path(stem.dir, leave.dir)
    dir.create(leave.path, mode = '755')
    leaves <- leave.dir |> str_extract('GSE\\d+') |>
      str_subset(paths, pattern = _)
    message(str_glue('Copying {length(leaves)} file(s)'))
    file.copy(leaves, leave.path)
  }
  leave.dirs |> walk(grow_leave)
}

paths |>
  grow_db_tree(root.dir = '~/append-ssd/geo_array/')

c('psoriasis','IBD','RA','MS') |>
  walk(\(x)grow_db_tree(paths, '~/append-ssd/geo_array/', regex = x))
